import * as d3 from 'd3';
import { deepClone } from '@/utils/index';

const bubble = ({
  seriesData = [],
  textData = [],
  color = [
    '#CF4645',
    '#B580B2',
    '#29008A',
    '#146A90',
    '#8956FF',
    '#70C9A8',
    '#bfbfbf',
    '#595959',
    '#40a9ff',
    '#1890ff',
    '#ffd666',
    '#ffc53d',
    '#ffc53d',
    '#ffc069',
    '#ffa940',
    '#fa8c16',
    '#eccbd9',
    '#ffadad',
    '#ff6392',
    '#ffc09f',
    '#ffcb77',
    '#ffe066',
    '#ffd53e',
    '#ffda3d',
    '#adf7b6',
    '#a0e8af',
    '#80ed99',
    '#07beb8',
    '#17c3b2',
    '#48cae4',
    '#97d2fb',
    '#83bcff',
    '#91e5f6',
    '#9381ff',
  ],
  padding = 0, // 气泡间距
  showPercent = false,
}) => {
  seriesData.unshift({
    id: 'option',
    value: 0,
  });

  let total = 0;
  if (showPercent) {
    total = seriesData.reduce((pre, item) => {
      return (pre += item.value);
    }, 0);
  }

  let displayRoot = d3
    .stratify()
    .parentId(function (d) {
      return d.id.substring(0, d.id.lastIndexOf('.'));
    })(seriesData)
    .sum(function (d) {
      return d.value || 0;
    })
    .sort(function (a, b) {
      return b.value - a.value;
    });

  function overallLayout(params, api) {
    let context = params.context;
    d3
      .pack()
      .size([api.getWidth() - 2, api.getHeight() - 2])
      .padding(padding)(displayRoot); // 设置气泡间距
    context.nodes = {};
    displayRoot.descendants().forEach(function (node) {
      context.nodes[node.id] = node;
    });
  }

  function renderItem(params, api) {
    let context = params.context;
    let idx = params.dataIndex;

    // Only do that layout once in each time `setOption` called.
    // 每次调用“setOption”时，只能进行一次布局。
    if (!context.layout) {
      context.layout = true;
      overallLayout(params, api);
    }

    let nodePath = api.value('id');
    let nodeName = nodePath
      .slice(nodePath.lastIndexOf('.') + 1)
      .split(/(?=[A-Z][^A-Z])/g)
      .join('\n');
    let nodeValue = api.value('value');
    let textValue = textData.find((item) => item.name == nodeName);
    textValue = textValue ? textValue.value : null;
    let node = context.nodes[nodePath];
    if (node.id === 'option') node.r = 0;
    if (node.id === 'option.temp') node.r = 0;
    // Reder nothing.
    if (!node) return;

    let z2 = api.value('depth') * 2;
    return {
      type: 'circle',
      shape: {
        cx: node.x,
        cy: node.y,
        r: node.r,
      },
      // transition: ['shape'],
      z2: z2,
      textContent: {
        type: 'text',
        style: {
          // transition: isLeaf ? 'fontSize' : null,
          text: showPercent ? `${nodeName}\n${((textValue / total) * 100).toFixed(2)}%` : `${nodeName}`,
          fill: '#fff',
          fontFamily: 'Arial',
          width: node.r * 1.3,
          overflow: 'truncate',
          fontSize: node.r / 3,
        },
        emphasis: {
          style: {
            overflow: null,
            fontSize: Math.max(node.r / 3, 12),
          },
        },
      },
      textConfig: {
        position: 'inside',
      },
      style: {
        fill: color[idx % color.length],
        opacity: 0.5,
      },
      emphasis: {
        style: {
          fontFamily: 'Arial',
          fontSize: 12,
          shadowBlur: 20,
          shadowOffsetX: 3,
          shadowOffsetY: 5,
          shadowColor: 'rgba(0,0,0,0.3)',
        },
      },
    };
  }

  const defaultConfig = {
    dataset: {
      source: seriesData,
    },
    tooltip: {
      confine: true,
      axisPointer: { type: 'shadow' },
      trigger: 'item',
      formatter(params) {
        let name = params.name.split('.')[1];
        let textValue = textData.find((item) => item.name == name);
        textValue = textValue ? textValue.value : null;
        let content = `${name}：<span style="font-weight:bold;">${textValue}</span><br />`;
        if (showPercent)
          content += `占比：<span style="font-weight:bold;">${((textValue / total) * 100).toFixed(2)}%</span>`;
        return content;
      },
    },
    hoverLayerThreshold: Infinity,
    series: [
      {
        type: 'custom',
        colorBy: 'data',
        cursor: 'auto',
        renderItem: renderItem,
        progressive: 0,
        coordinateSystem: 'none',
        encode: {
          tooltip: 'value',
          itemName: 'id',
        },
      },
    ],
  };

  const opt = deepClone(defaultConfig);
  return opt;
};

export default {
  bubble,
};
